#include "all.h"

libco::Channel<int> channel;

void sender(libco::Channel<int>& channel, int value) {
    std::cout << "Sending: " << value << std::endl;
    channel << value;
    std::cout << "Sent: " << value << std::endl;
}

void receiver(libco::Channel<int>& channel) {
    std::cout << "Receiving: " << std::endl;
    int value;
    channel >> value;
    std::cout << "Received: " << value << std::endl;
}

void test1() {
    // 创建发送者和接收者线程
    libco::Thread t2(std::bind(receiver, std::ref(channel)));

    sleep(3);
    libco::Thread t1(std::bind(sender, std::ref(channel), 42));

    // 等待线程完成
    t1.join();
    t2.join();
}

void test2() {

    // 创建发送者和接收者线程
    libco::Thread t1(std::bind(sender, std::ref(channel), 42));

    sleep(3);
    libco::Thread t2(std::bind(receiver, std::ref(channel)));

    // 等待线程完成
    t1.join();
    t2.join();
}

void test_block() {
    test2();

    std::cout << std::endl;
    sleep(1);

    test1();

    std::cout << std::endl;
    sleep(1);

    test1();

    std::cout << std::endl;
    sleep(1);

    test2();

    std::cout << std::endl;
    sleep(1);

    test2();
}

int main() {
    test_block();

    // // 测试无缓冲的阻塞式channel
    // std::cout << "Testing unbuffered channel:" << std::endl;
    // libco::Channel<int> unbuffered_channel(0);

    // std::thread t1(sender, std::ref(unbuffered_channel), 42);
    // std::thread t2(receiver, std::ref(unbuffered_channel));

    // t1.join();
    // t2.join();

    // // 测试带缓冲的channel
    // std::cout << "Testing buffered channel:" << std::endl;
    // libco::Channel<int> buffered_channel(2);

    // std::thread t3(sender, std::ref(buffered_channel), 1);
    // std::thread t4(sender, std::ref(buffered_channel), 2);
    // std::thread t5(receiver, std::ref(buffered_channel));
    // std::thread t6(receiver, std::ref(buffered_channel));

    // t3.join();
    // t4.join();
    // t5.join();
    // t6.join();

    // // 测试关闭通道
    // std::cout << "Testing closing channel:" << std::endl;
    // libco::Channel<int> closing_channel(1);

    // std::thread t7(sender, std::ref(closing_channel), 99);
    // std::thread t8(receiver, std::ref(closing_channel));

    // t7.join();
    // t8.join();

    // closing_channel.close();

    // std::thread t9([&]() {
    //     try {
    //         int value;
    //         closing_channel >> value;
    //         std::cout << "Received: " << value << std::endl;
    //     } catch (const std::exception& e) {
    //         std::cerr << "Exception caught: " << e.what() << std::endl;
    //     }
    // });

    // t9.join();

    return 0;
}